package com.xyzwps.webfluxjava.common.exception;

import lombok.val;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindingResult;


/**
 * <a href="https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html">Http Status Code Definitions</a>
 * <ul>
 *     <li>400: Bad Request</li>
 *     <li>500: Internal Server Error</li>
 *     <li>503: Service Unavailable</li>
 * </ul>
 */
public abstract class BizException extends RuntimeException {

	private static final long serialVersionUID = -4139287267464718514L;

	public static BizException badRequestError(String reason) {
        return badRequestError(reason, null);
    }

    public static BizException badRequestError(String reason, Throwable cause) {
        return new BizClientError(reason, cause);
    }

    public static void checkBindingResult(BindingResult br) {
        if (br == null) return;

        val errors = br.getAllErrors();
        if (errors.size() == 0) return;

        val firsrError = errors.get(0);

        throw badRequestError(firsrError.getDefaultMessage());
    }

    protected BizException(String reason, Throwable cause) {
        super(reason, cause);
    }

    public abstract HttpStatus getStatus();
}

class BizServiceError extends BizException {

	private static final long serialVersionUID = 2372750369192406027L;

	public BizServiceError(String reason, Throwable cause) {
        super(reason, cause);
    }

    @Override
    public HttpStatus getStatus() {
        return HttpStatus.SERVICE_UNAVAILABLE;
    }
}

class BizClientError extends BizException {

	private static final long serialVersionUID = 1455646698412311081L;

	public BizClientError(String reason, Throwable cause) {
        super(reason, cause);
    }

    @Override
    public HttpStatus getStatus() {
        return HttpStatus.BAD_REQUEST;
    }
}
